package zzzhc.image.ui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;

import zzzhc.image.model.AppModel;
import zzzhc.image.model.OpPanelModel;
import zzzhc.image.model.OpTableModel;
import zzzhc.image.recognize.Filter;
import zzzhc.image.recognize.FilterManager;
import zzzhc.image.recognize.ImageToken;
import zzzhc.image.recognize.RecognizeContext;
import zzzhc.image.recognize.SplitFilter;
import zzzhc.image.recognize.TokenUtil;
import zzzhc.image.recognize.filter.BinaryFilter;
import zzzhc.image.recognize.filter.BlockSplitFilter;
import zzzhc.image.recognize.filter.BorderFilter;
import zzzhc.image.recognize.filter.ClearFilter;
import zzzhc.image.recognize.filter.ContinueSplitFilter;
import zzzhc.image.recognize.filter.DropThinFilter;
import zzzhc.image.recognize.filter.GrayFilter;
import zzzhc.image.recognize.filter.GrayLevelFilter;
import zzzhc.image.recognize.filter.LineFilter;
import zzzhc.image.recognize.filter.MixFilter;
import zzzhc.image.recognize.filter.NormalizeFilter;
import zzzhc.image.recognize.filter.PenWidthFilter;
import zzzhc.image.recognize.filter.RemoveNoiseFilter;
import zzzhc.image.recognize.filter.SkeletonizeFilter;
import zzzhc.image.recognize.filter.StandardSplitFilter;
import javax.swing.ListSelectionModel;

public class OperatePanel extends JPanel {

	private static final long serialVersionUID = 1L;

	private JToolBar jToolBar = null;

	private JLabel originLabel = null;

	private JScrollPane jScrollPane = null;

	private JTable jTable = null;

	private JButton jButton = null;

	private JToolBar jToolBar1 = null;

	private JButton jButton2 = null;

	private OpPanelModel model = AppModel.getInstance().getOpPanelModel(); // @jve:decl-index=0:

	private OpTableModel imageTableModel = new OpTableModel();

	private JComboBox jComboBox = null;

	private JLabel currentLabel = null;

	private JLabel jLabel = null;

	private JButton jButton1 = null;

	private JButton jButton3 = null;

	private JButton jButton4 = null;

	private JButton jButton5 = null;

	private JButton jButton6 = null;

	private JButton jButton7 = null;

	private JButton jButton8 = null;

	private JButton jButton9 = null;

	public OpPanelModel getModel() {
		return model;
	}

	public void setOriginImage(BufferedImage image) {
		model.setOriginImage(image);
		originLabel.setIcon(new ImageIcon(image));
	}

	/**
	 * This is the default constructor
	 */
	public OperatePanel() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
		gridBagConstraints21.gridx = 1;
		gridBagConstraints21.anchor = GridBagConstraints.WEST;
		gridBagConstraints21.fill = GridBagConstraints.NONE;
		gridBagConstraints21.gridy = 3;
		GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
		gridBagConstraints4.gridx = 0;
		gridBagConstraints4.anchor = GridBagConstraints.EAST;
		gridBagConstraints4.gridy = 2;
		jLabel = new JLabel();
		jLabel.setText("选择图片:");
		currentLabel = new JLabel();
		currentLabel.setText("转换结果");
		GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
		gridBagConstraints11.fill = GridBagConstraints.VERTICAL;
		gridBagConstraints11.gridy = 2;
		gridBagConstraints11.weightx = 1.0;
		gridBagConstraints11.gridwidth = 1;
		gridBagConstraints11.anchor = GridBagConstraints.WEST;
		gridBagConstraints11.insets = new Insets(0, 5, 0, 0);
		gridBagConstraints11.gridx = 1;
		GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
		gridBagConstraints3.fill = GridBagConstraints.BOTH;
		gridBagConstraints3.gridy = 1;
		gridBagConstraints3.weightx = 1.0;
		gridBagConstraints3.anchor = GridBagConstraints.WEST;
		gridBagConstraints3.gridwidth = 3;
		gridBagConstraints3.gridx = 0;
		GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
		gridBagConstraints2.fill = GridBagConstraints.BOTH;
		gridBagConstraints2.gridy = 4;
		gridBagConstraints2.weightx = 1.0;
		gridBagConstraints2.weighty = 1.0;
		gridBagConstraints2.gridwidth = 3;
		gridBagConstraints2.gridx = 0;
		GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
		gridBagConstraints1.gridx = 0;
		gridBagConstraints1.anchor = GridBagConstraints.EAST;
		gridBagConstraints1.gridy = 3;
		originLabel = new JLabel();
		originLabel.setText("原始图片");
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.anchor = GridBagConstraints.WEST;
		gridBagConstraints.gridwidth = 3;
		gridBagConstraints.gridx = 0;
		this.setSize(600, 450);
		this.setLayout(new GridBagLayout());
		this.add(getJToolBar(), gridBagConstraints);
		this.add(originLabel, gridBagConstraints1);
		this.add(getJScrollPane(), gridBagConstraints2);
		this.add(getJToolBar1(), gridBagConstraints3);
		this.add(getJComboBox(), gridBagConstraints11);
		this.add(jLabel, gridBagConstraints4);
		this.add(getJPanel(), gridBagConstraints21);
		this.addFocusListener(new java.awt.event.FocusAdapter() {
			public void focusGained(java.awt.event.FocusEvent e) {
				OperatePanel.this.updateUI();
			}
		});
	}

	/**
	 * This method initializes jToolBar
	 * 
	 * @return javax.swing.JToolBar
	 */
	private JToolBar getJToolBar() {
		if (jToolBar == null) {
			jToolBar = new JToolBar();
			jToolBar.add(getJButton4());
			jToolBar.add(getJButton7());
			jToolBar.add(getJButton());
			jToolBar.add(getJButton8());
			jToolBar.add(getJButton3());
			jToolBar.add(getJButton11());
			jToolBar.add(getJButton5());
			jToolBar.add(getJButton12());
			jToolBar.add(getJButton13());
			jToolBar.add(getJButton14());
			jToolBar.add(getJButton6());
		}
		return jToolBar;
	}

	/**
	 * This method initializes jScrollPane
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getJTable());
		}
		return jScrollPane;
	}

	/**
	 * This method initializes jTable
	 * 
	 * @return javax.swing.JTable
	 */
	private JTable getJTable() {
		if (jTable == null) {
			jTable = new JTable();
			jTable.setRowHeight(100);
			jTable.setCellSelectionEnabled(true);
			jTable.setShowGrid(true);
			jTable
					.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
			jTable.setModel(imageTableModel);
			ImageTableCellRenderer renderer = new ImageTableCellRenderer();
			jTable.setDefaultRenderer(Image.class, renderer);
		}
		return jTable;
	}

	/**
	 * This method initializes jButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.setText("二值化");
			jButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new BinaryFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton;
	}

	private void doFilter(Filter filter, boolean notRedo) {
		BufferedImage image = getModel().getOriginImage();
		if (image == null) {
			return;
		}
		if (notRedo && FilterUtil.hasProperties(filter)) {
			FilterSettingDialog dialog = new FilterSettingDialog(Gui
					.getInstance(), filter);
			dialog.setModal(true);
			dialog.setVisible(true);
			if (dialog.isDoOperate() == false) {
				return;
			}
		}
		FilterManager manager = getModel().getFilterManager();
		manager.addFilter(filter);
		RecognizeContext source = getModel().getSource();
		if (source == null) {
			source = new RecognizeContext(image);
			getModel().setSource(source);
		}
		filter.doFilter(source);
		// source.show();
		if (filter instanceof SplitFilter) {
			splitTokens.addAll(source.getTokens());
		}
		BufferedImage currentImage = source.toImage();
		getModel().setCurrentImage(currentImage);
		currentLabel.setText("");
		currentLabel.setIcon(new ImageIcon(scaleImage(currentImage)));

		ImageToken[] tokens = source.getTokens().toArray(new ImageToken[0]);
		if (tokens.length > 0) {
			String code = getModel().getCode();
			imageTableModel.clearAll();
			for (int index = 0; index < tokens.length; index++) {
				ImageToken token = tokens[index];
				ImageToken splitToken = splitTokens.get(index);
				BufferedImage image1 = splitToken.toImage();
				BufferedImage image2 = token.toImage();

				String s = "";
				if (index < code.length()) {
					s = code.substring(index, index + 1);
				}
				String wh = "w=" + splitToken.w + ",h=" + splitToken.h
						+ ",count=" + splitToken.getOneCount();
				imageTableModel.addColumn(image1, image2, s, wh, token
						.toNNString());
			}
		}
	}

	/**
	 * This method initializes jToolBar1
	 * 
	 * @return javax.swing.JToolBar
	 */
	private JToolBar getJToolBar1() {
		if (jToolBar1 == null) {
			jToolBar1 = new JToolBar();
			jToolBar1.add(getJButton10());
			jToolBar1.add(getJButton2());
			jToolBar1.add(getJButton1());
			jToolBar1.add(getJButton9());
			jToolBar1.add(getRedoButton());
		}
		return jToolBar1;
	}

	/**
	 * This method initializes jButton2
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton2() {
		if (jButton2 == null) {
			jButton2 = new JButton();
			jButton2.setText("连续图片分割");
			jButton2.setActionCommand("连续图片分割");
			jButton2.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					ContinueSplitFilter generator = new ContinueSplitFilter();
					splitPerform(generator);
				}
			});
		}
		return jButton2;
	}

	private ArrayList<ImageToken> splitTokens = new ArrayList<ImageToken>(); // @jve:decl-index=0:

	private JButton redoButton = null;

	private JButton jButton10 = null;

	private JPanel jPanel = null;

	private JButton jButton11 = null;

	private JButton jButton12 = null;

	private JButton jButton13 = null;

	private JButton jButton14 = null;

	private void splitPerform(Filter filter) {
		splitTokens.clear();
		if (FilterUtil.hasProperties(filter)) {
			FilterSettingDialog dialog = new FilterSettingDialog(Gui
					.getInstance(), filter);
			dialog.setModal(true);
			dialog.setVisible(true);
			if (dialog.isDoOperate() == false) {
				return;
			}
		}
		filter.doFilter(getModel().getSource());
		ImageToken[] tokens = getModel().getSource().getTokens().toArray(
				new ImageToken[0]);
		splitTokens.addAll(getModel().getSource().getTokens());
		String code = getModel().getCode();
		int index = 0;
		if (code.length() != tokens.length) {
			JOptionPane.showConfirmDialog(OperatePanel.this,
					"token数与字符数不相等,token数=" + tokens.length + ",字符数="
							+ code.length(), "错误", JOptionPane.YES_OPTION);
		}
		getModel().getFilterManager().addFilter(filter);
		AppModel.getInstance().setFilter(getModel().getFilterManager());
		imageTableModel.clearAll();
		for (ImageToken token : tokens) {
			BufferedImage image1 = token.toImage();
			ImageToken convertToken = TokenUtil.convert(token);
			BufferedImage image2 = convertToken.toImage();

			String s = "";
			if (index < code.length()) {
				s = code.substring(index, index + 1);
			}
			String wh = "w=" + token.w + ",h=" + token.h + ",count="
					+ token.getOneCount();
			imageTableModel.addColumn(image1, image2, s, wh, convertToken
					.toNNString());
			index++;
		}
	}

	/**
	 * This method initializes jComboBox
	 * 
	 * @return javax.swing.JComboBox
	 */
	private JComboBox getJComboBox() {
		if (jComboBox == null) {
			jComboBox = new JComboBox();
			jComboBox.setRenderer(new ImageListCellRender());
			jComboBox.addFocusListener(new java.awt.event.FocusAdapter() {
				public void focusGained(java.awt.event.FocusEvent e) {
					if (getModel().getCaptureTableModel() == null) {
						return;
					}
					DefaultComboBoxModel comboModel = new DefaultComboBoxModel();
					List<BufferedImage> list = getModel()
							.getCaptureTableModel().getImages();
					for (BufferedImage image : list) {
						comboModel.addElement(image);
					}
					jComboBox.setModel(comboModel);
				}
			});
			jComboBox.addItemListener(new java.awt.event.ItemListener() {
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					if (e.getStateChange() == ItemEvent.SELECTED) {
						BufferedImage image = (BufferedImage) jComboBox
								.getSelectedItem();
						if (image == null) {
							return;
						}
						getModel().setOriginImage(image);
						getModel().setImageIndex(jComboBox.getSelectedIndex());
						FilterManager lastFilterManager = new FilterManager(
								getModel().getFilterManager());
						if (lastFilterManager.size() > 0) {
							getModel().setLastFilterManager(lastFilterManager);
						}
						redoButton.setEnabled(true);
						getModel().getFilterManager().clear();
						getModel().setSource(null);
						originLabel.setText("");
						originLabel.setIcon(new ImageIcon(scaleImage(image)));
						currentLabel.setText("转换结果");
						currentLabel.setIcon(null);
						imageTableModel.clearAll();
						splitTokens.clear();
					}
				}
			});
		}
		return jComboBox;
	}

	public Image scaleImage(BufferedImage image) {
		if (image == null) {
			return null;
		}
		int w = image.getWidth();
		int h = image.getHeight();
		int scale = 2;
		return image
				.getScaledInstance(w * scale, h * scale, Image.SCALE_SMOOTH);
	}

	/**
	 * This method initializes jButton1
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton1() {
		if (jButton1 == null) {
			jButton1 = new JButton();
			jButton1.setText("块分割");
			jButton1.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					BlockSplitFilter generator = new BlockSplitFilter();
					splitPerform(generator);
				}
			});
		}
		return jButton1;
	}

	/**
	 * This method initializes jButton3
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton3() {
		if (jButton3 == null) {
			jButton3 = new JButton();
			jButton3.setText("清除杂点");
			jButton3.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new ClearFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton3;
	}

	/**
	 * This method initializes jButton4
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton4() {
		if (jButton4 == null) {
			jButton4 = new JButton();
			jButton4.setText("灰化");
			jButton4.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					GrayFilter filter = new GrayFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton4;
	}

	/**
	 * This method initializes jButton5
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton5() {
		if (jButton5 == null) {
			jButton5 = new JButton();
			jButton5.setText("去边框");
			jButton5.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new BorderFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton5;
	}

	/**
	 * This method initializes jButton6
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton6() {
		if (jButton6 == null) {
			jButton6 = new JButton();
			jButton6.setText("提取骨架");
			jButton6.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new SkeletonizeFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton6;
	}

	/**
	 * This method initializes jButton7
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton7() {
		if (jButton7 == null) {
			jButton7 = new JButton();
			jButton7.setText("灰度选择");
			jButton7.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new GrayLevelFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton7;
	}

	/**
	 * This method initializes jButton8
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton8() {
		if (jButton8 == null) {
			jButton8 = new JButton();
			jButton8.setText("消除细线");
			jButton8.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new DropThinFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton8;
	}

	/**
	 * This method initializes jButton9
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton9() {
		if (jButton9 == null) {
			jButton9 = new JButton();
			jButton9.setText("规格化");
			jButton9.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new NormalizeFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton9;
	}

	/**
	 * This method initializes redoButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getRedoButton() {
		if (redoButton == null) {
			redoButton = new JButton();
			redoButton.setText("重做");
			redoButton.setEnabled(true);
			redoButton.setToolTipText("对当前图片重做上一次所有过滤操作");
			redoButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					FilterManager lastFilterManager = getModel()
							.getLastFilterManager();
					if (lastFilterManager == null) {
						return;
					}
					Iterator<Filter> ite = lastFilterManager.iterator();
					while (ite.hasNext()) {
						doFilter(ite.next(), false);
					}
				}
			});
		}
		return redoButton;
	}

	/**
	 * This method initializes jButton10
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton10() {
		if (jButton10 == null) {
			jButton10 = new JButton();
			jButton10.setText("标准分割");
			jButton10.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter generator = new StandardSplitFilter();
					splitPerform(generator);
				}
			});
		}
		return jButton10;
	}

	/**
	 * This method initializes jPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 0;
			gridBagConstraints6.anchor = GridBagConstraints.WEST;
			gridBagConstraints6.insets = new Insets(0, 5, 0, 5);
			gridBagConstraints6.gridy = 0;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.anchor = GridBagConstraints.WEST;
			gridBagConstraints5.insets = new Insets(0, 5, 0, 0);
			gridBagConstraints5.gridx = 1;
			gridBagConstraints5.gridy = -1;
			gridBagConstraints5.fill = GridBagConstraints.HORIZONTAL;
			jPanel = new JPanel();
			jPanel.setLayout(new GridBagLayout());
			jPanel.add(currentLabel, gridBagConstraints5);
		}
		return jPanel;
	}

	/**
	 * This method initializes jButton11
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton11() {
		if (jButton11 == null) {
			jButton11 = new JButton();
			jButton11.setText("过滤噪声");
			jButton11.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new RemoveNoiseFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton11;
	}

	/**
	 * This method initializes jButton12
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton12() {
		if (jButton12 == null) {
			jButton12 = new JButton();
			jButton12.setText("删除长线");
			jButton12.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new LineFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton12;
	}

	/**
	 * This method initializes jButton13
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton13() {
		if (jButton13 == null) {
			jButton13 = new JButton();
			jButton13.setText("消除混合背景");
			jButton13.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Filter filter = new MixFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton13;
	}

	/**
	 * This method initializes jButton14
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton14() {
		if (jButton14 == null) {
			jButton14 = new JButton();
			jButton14.setText("笔宽过滤");
			jButton14.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					PenWidthFilter filter = new PenWidthFilter();
					doFilter(filter, true);
				}
			});
		}
		return jButton14;
	}

	public static void main(String[] args) {
		OperatePanel panel = new OperatePanel();
		PanelLauncher launcher = new PanelLauncher(panel);
		launcher.show(400, 300);
	}
}
